package cos480.amiwsd;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;


/**
 * 
 * SearchMgmt:
 * 
 * This is the Search management class. This provides methods for searching 
 * for landscapes and simulation results which fit some given criteria.
 * 
 * @author will, emma
 *
 */


public class SearchMgmt {

	/**
	 * Search the simulation results for those matching the given parameters.
	 * 
	 * @param sql the PostgreSQL Statement object
	 * @param params to search on
	 * @return PostgreSQL query string
	 */
	public String searchSimResults(Statement sql, HashMap<String,String> s) {
		
		String queryOutput = "select si.type, 256, si.instance_id, si.minTime, si.maxTime, si.i0, " +
				"si.mu, si.gamma, si.phi, si.p_0, si.p_1, si.p_2, si.crnum, sr.qn, sr.qhh, sr.peak_i_qn, sr.peak_i_qhh, " +
				"sr.igr, sr.peak_i, sr.final_i_avg, sr.ncount, sr.peak_in_count " +
				"from simresult sr, simulation si " +
				"where sr.s_id = si.s_id ";		
		
		if (s.get("filename") != null) {
			queryOutput += " and sr.filename = '" + s.get("filename") + "'";
		}
		if (s.get("numSims") != null) {
			queryOutput += " and si.numsims = " + s.get("numSims"); 
		}
		if (s.get("mu") != null) {
			queryOutput += " and si.mu = " + s.get("mu");
		}
		if (s.get("phi") != null) {
			queryOutput += " and si.phi = " + s.get("phi");
		}
		if (s.get("gamma") != null) {
			queryOutput += " and si.gamma = " + s.get("gamma");
		}
		if (s.get("simType") != null) {
			queryOutput += " and si.type = '" + s.get("simType") + "'";
		}
		if (s.get("minTime") != null) {
			queryOutput += " and si.mintime = " + s.get("minTime");
		}
		if (s.get("maxTime") != null) {
			queryOutput += " and si.maxtime = " + s.get("maxTime");
		}
		if (s.get("I0") != null) {
			queryOutput += " and si.I0 = " + s.get("I0");
		}
		if (s.get("CRnum") != null) {			
			queryOutput += " and si.crnum = " + s.get("CRnum");
		}
		if (s.get("p0") != null) {			
			queryOutput += " and si.p_0 = " + s.get("p0");
		}
		if (s.get("p1") != null) {			
			queryOutput += " and si.p_1 = " + s.get("p1");
		}
		if (s.get("p2") != null) {			
			queryOutput += " and si.p_2 = " + s.get("p2");
		}
		
		
		System.out.println("Searching for sim results: \n");
		//System.out.println(queryOutput);
		
		try {
			ResultSet rs = sql.executeQuery(queryOutput);
			//System.out.println("Finished the query.");
			System.out.format("%-10s\t%-10s\t%-10s\t%-4s\t%-10s\t%-10s\t%-10s\t%-5s\t%-5s%n", "p_0", "p_1", "p_2", "type", "mu", "gamma", "phi", "minTime", "maxTime");
			while (rs.next()) {
				//MINTIME 4 MAXTIME 5 MU  GAMMA PHI
				System.out.format("%-10g\t%-10g\t%-10g\t%-4s\t%-10g\t%-10g\t%-10g\t%-5d\t%-5d%n", rs.getDouble(10),rs.getDouble(11),rs.getDouble(12), rs.getString(1),rs.getDouble(7), rs.getDouble(8), rs.getDouble(9), rs.getInt(4), rs.getInt(5));
				//System.out.println("type:" + rs.getString(1) + "\tminTime:" + rs.getInt(4) + "\tmaxTime:" + rs.getInt(5) + "\tmu:" + rs.getDouble(7) + "\tgamma:" + rs.getDouble(8) + "\tphi:" + rs.getDouble(9) + "\tp0:" + rs.getDouble(10) + "\tp1:" + rs.getDouble(11) + "\tp2:" + rs.getDouble(12));
			}
			
		} catch (SQLException e) {
			// TODO: handle exception
			System.out.println("failed to execute the query.");
			e.printStackTrace();
		}
		
		System.out.println("Finished searching for sim results.\n");
		
		return queryOutput;
		
	}
	
	/**
	 * Search the sets of simulation parameters for those matching the given parameters.
	 * 
	 * @param sql the PostgreSQL Statement object
	 * @param params to search on
	 * @return PostgreSQL query string
	 */
	public String searchSimParams(Statement sql, HashMap<String,String> params){
		
		String queryOutput = "select * from simulation si ";
		boolean needsAnd = false, needsWhere = true;;
		//TODO: add file name here...
		
		if (params.get("filename") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " si.filename = '" + params.get("filename") + "'"; 
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("numSims") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " si.numsims = " + params.get("numSims"); 
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("mu") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " and si.mu = " + params.get("mu");
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("phi") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " and si.phi = " + params.get("phi");
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("gamma") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " and si.gamma = " + params.get("gamma");
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("simType") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " and si.type = '" + params.get("simType") + "'";
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("minTime") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " and si.mintime = " + params.get("minTime");
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("maxTime") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " and si.maxtime = " + params.get("maxTime");
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("I0") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " and si.I0 = " + params.get("I0");
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("CRnum") != null) {	
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " and si.crnum = " + params.get("CRnum");
		}
		
		//System.out.println("Query for sim params: \n");
		//System.out.println(queryOutput);
		
		System.out.println("Searching for sim params:\n");
		
		try {
			ResultSet rs = sql.executeQuery(queryOutput);
			System.out.println("Finished the query.");
			System.out.format("%n%-10s\t%-10s\t%-10s\t%-4s%n", "p_0", "p_1", "p_2", "type");
			while (rs.next()) {
				System.out.format("%-10g\t%-10g\t%-10g\t%-4s%n", rs.getDouble(9), rs.getDouble(10), rs.getDouble(11), rs.getString(1));
				System.out.println("type:" + rs.getString(1) + "\tp0:" + rs.getDouble(9) + "\tp1:" + rs.getDouble(10) + "\tp2:" + rs.getDouble(11));
			}
			
		} catch (SQLException e) {
			// TODO: handle exception
			System.out.println("failed to execute the query.");
			e.printStackTrace();
		}
		
		System.out.println("Finished searching for sim params.\n");
		
		return queryOutput;
	}
	
	public String searchScanResults(Statement sql, HashMap<String,String> params){
		String queryOutput = "select ros.ip, s.scan_date, s.success, ros.result from resultofscan ros, scan s where s.scan_id = ros.scan_id ";
		String ip;
		boolean needsAnd = true, needsWhere = false;
		//TODO: add file name here...
		
		if (params.get("ip") != null) {
			ip = params.get("ip");
			ip += "/" + (((ip.split("\\.").length-1)*8) + 8);
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " ros.ip <<= '" + ip + "'::inet"; 
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("scanDate") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " s.scan_date = '" + params.get("scanDate") + "'"; 
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("result") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " and ros.result like '%" + params.get("result") + "%'";
			needsAnd = true;
			needsWhere = false;
		}
		if (params.get("success") != null) {
			queryOutput += (needsWhere ? " where " : "");
			queryOutput += (needsAnd ? " and " : "");
			queryOutput += " and s.success = '" + params.get("success") + "'";
			needsAnd = true;
			needsWhere = false;
		}
		
		//System.out.println("Query for sim params: \n");
		//System.out.println(queryOutput);
		
		System.out.println("Searching for scan results...");
		try {
			//System.out.println("query: " + queryOutput);
			ResultSet rs = sql.executeQuery(queryOutput);
			System.out.println("Finished executing the query:");
			System.out.format("%n%-15s\t%-10s\t%s\t%s%n", "IP address", "scan date", "success", "result");
			while (rs.next()) {
				System.out.format("%-15s\t%-10s\t%s\t%s%n", rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4));
			}
			
		} catch (SQLException e) {
			// TODO: handle exception
			System.out.println("failed to execute the query: " + e.getMessage());
			e.printStackTrace();
		}
		
		System.out.println("Finished searching for scan results.\n");
		
		return queryOutput;
	}	
}
